home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
051-075
/
051
/
bison
/
closure.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-13
|
8KB
|
385 lines
/* Subroutines for bison, copyright (C) 1984 Bob Corbett and Richard Stallman
Permission is granted to anyone to make or distribute verbatim copies of this program
provided that the copyright notice and this permission notice are preserved;
and provided that the recipient is not asked to waive or limit his right to
redistribute copies as permitted by this permission notice;
and provided that anyone possessing an executable copy
is granted access to copy the source code, in machine-readable form,
in some reasonable manner.
Permission is granted to distribute derived works or enhanced versions of
this program under the above conditions with the additional condition
that the entire derivative or enhanced work
must be covered by a permission notice identical to this one.
Anything distributed as part of a package containing portions derived
from this program, which cannot in current practice perform its function usefully
in the absense of what was derived directly from this program,
is to be considered as forming, together with the latter,
a single work derived from this program,
which must be entirely covered by a permission notice identical to this one
in order for distribution of the package to be permitted.
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding! */
/* subroutines of file LR0.c.
Entry points:
closure (items, n)
Given a vector of item numbers items, of length n,
set up ruleset and itemset to indicate what rules could be run
and which items could be accepted when those items are the active ones.
ruleset contains a bit for each rule. closure sets the bits
for all rules which could potentially describe the next input to be read.
itemset is a vector of item numbers; itemsetend points to just beyond the end
of the part of it that is significant.
closure places there the indices of all items which represent units of
input that could arrive next.
initialize_closure (n)
Allocates the itemset and ruleset vectors,
and precomputes useful data so that closure can be called.
n is the number of elements to allocate for itemset.
finalize_closure ()
Frees itemset, ruleset and internal data.
*/
#include <stdio.h>
#include "machine.h"
#include "new.h"
#include "gram.h"
extern short **derives;
short *itemset;
short *itemsetend;
static unsigned *ruleset;
/* internal data. See comments before set_fderives and set_firsts. */
static unsigned *fderives;
static unsigned *firsts;
/* number of words required to hold a bit for each rule */
static int rulesetsize;
/* number of words required to hold a bit for each variable */
static int varsetsize;
initialize_closure(n)
int n;
{
itemset = NEW2(n, short);
rulesetsize = WORDSIZE(nrules + 1);
ruleset = NEW2(rulesetsize, unsigned);
set_fderives();
}
/* set fderives to an nvars by nrules matrix of bits
indicating which rules can help derive the beginning of the data
for each nonterminal. For example, if symbol 5 can be derived as
the sequence of symbols 8 3 20, and one of the rules for deriving
symbol 8 is rule 4, then the [5 - ntokens, 4] bit in fderives is set. */
set_fderives()
{
register unsigned *rrow;
register unsigned *vrow;
register int j;
register unsigned mask;
register unsigned cword;
register short *rp;
int ruleno;
int i;
fderives = NEW2(nvars * rulesetsize, unsigned) - ntokens * rulesetsize;
set_firsts();
rrow = fderives + ntokens * rulesetsize;
for (i = ntokens; i < nsyms; i++)
{
vrow = firsts + ((i - ntokens) * varsetsize);
cword = *vrow++;
mask = 1;
for (j = ntokens; j < nsyms; j++)
{
if (cword & mask)
{
rp = derives[j];
while ((ruleno = *rp++) > 0)
{
SETBIT(rrow, ruleno);
}
}
mask <<= 1;
if (mask == 0)
{
cword = *vrow++;
mask = 1;
}
}
vrow += varsetsize;
rrow += rulesetsize;
}
#ifdef DEBUG
print_fderives();
#endif
FREE(firsts);
}
/* set firsts to be an nvars by nvars bit matrix indicating which items
can represent the beginning of the input corresponding to which other items.
For example, if some rule expands symbol 5 into the sequence of symbols 8 3 20,
the symbol 8 can be the beginning of the data for symbol 5,
so the bit [8 - ntokens, 5 - ntokens] in firsts is set. */
set_firsts()
{
register unsigned *row;
register int done;
register int symbol;
register short *sp;
register int rowsize;
int i;
varsetsize = rowsize = WORDSIZE(nvars);
firsts = NEW2(nvars * rowsize, unsigned);
row = firsts;
for (i = ntokens; i < nsyms; i++)
{
sp = derives[i];
while (*sp >= 0)
{
symbol = ritem[rrhs[*sp++]];
if (ISVAR(symbol))
{
symbol -= ntokens;
SETBIT(row, symbol);
}
}
row += rowsize;
}
RTC(firsts, nvars);
#ifdef DEBUG
print_firsts();
#endif
}
closure(core, n)
short *core;
int n;
{
register int ruleno;
register unsigned word;
register unsigned mask;
register short *csp;
register unsigned *dsp;
register unsigned *rsp;
short *csend;
unsigned *rsend;
int symbol;
int itemno;
rsp = ruleset;
rsend = ruleset + rulesetsize;
csend = core + n;
if (n == 0)
{
dsp = fderives + start_symbol * rulesetsize;
while (rsp < rsend)
*rsp++ = *dsp++;
}
else
{
while (rsp < rsend)
*rsp++ = 0;
csp = core;
while (csp < csend)
{
symbol = ritem[*csp++];
if (ISVAR(symbol))
{
dsp = fderives + symbol * rulesetsize;
rsp = ruleset;
while (rsp < rsend)
*rsp++ |= *dsp++;
}
}
}
ruleno = 0;
itemsetend = itemset;
csp = core;
rsp = ruleset;
while (rsp < rsend)
{
word = *rsp++;
if (word == 0)
{
ruleno += BITS_PER_WORD;
}
else
{
mask = 1;
while (mask)
{
if (word & mask)
{
itemno = rrhs[ruleno];
while (csp < csend && *csp < itemno)
*itemsetend++ = *csp++;
*itemsetend++ = itemno;
}
mask <<= 1;
ruleno++;
}
}
}
while (csp < csend)
*itemsetend++ = *csp++;
#ifdef DEBUG
print_closure(n);
#endif
}
finalize_closure()
{
FREE(itemset);
FREE(ruleset);
FREE(fderives + ntokens * rulesetsize);
}
#ifdef DEBUG
print_closure(n)
int n;
{
register short *isp;
printf("\n\nn = %d\n\n", n);
for (isp = itemset; isp < itemsetend; isp++)
printf(" %d\n", *isp);
}
print_firsts()
{
register int i;
register int j;
register unsigned *rowp;
register unsigned cword;
register unsigned mask;
extern char **tags;
printf("\n\n\nFIRSTS\n\n");
for (i = ntokens; i < nsyms; i++)
{
printf("\n\n%s firsts\n\n", tags[i]);
rowp = firsts + ((i - ntokens) * vrowsize);
cword = *rowp++;
mask = 1;
for (j = 0; j < nsyms; j++)
{
if (cword & mask)
printf(" %s\n", tags[j + ntokens]);
mask <<= 1;
if (mask == 0)
{
cword = *rowp++;
mask = 1;
}
}
}
}
print_fderives()
{
register int i;
register int j;
register unsigned *rp;
register unsigned cword;
register unsigned mask;
extern char **tags;
printf("\n\n\nFDERIVES\n");
for (i = ntokens; i < nsyms; i++)
{
printf("\n\n%s derives\n\n", tags[i]);
rp = fderives + i * rrowsize;
cword = *rp++;
mask = 1;
for (j = 0; j <= nrules; j++)
{
if (cword & mask)
printf(" %d\n", j);
mask <<= 1;
if (mask == 0)
{
cword = *rp++;
mask = 1;
}
}
}
fflush(stdout);
}
#endif